package com.weiun.common.core.handler;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.weiun.common.base.exception.*;
import com.weiun.common.core.controller.BaseApiController;
import com.weiun.common.base.bean.ParamBean;
import com.weiun.common.base.bean.ResultBean;
import com.weiun.common.base.exception.*;
import org.springframework.web.HttpMediaTypeException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

/**
 * Created by yaocai on 2017/12/5.
 *
 * @author yaocai
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Log log = LogFactory.get();

    private static final String ERROR = "[{}]-{}";

    /**
     * 统一异常处理
     *
     * @param request the request
     * @param ex      the ex
     * @return the api result
     */
    @ExceptionHandler
    @ResponseBody
    public ResultBean exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        ResultBean resultBean = null;
        String params = null;
        ParamBean apiParam = (ParamBean) request.getAttribute(BaseApiController.API_PARAM);
        if (apiParam == null) {
            Map parameterMap = request.getParameterMap();
            params = JSON.toJSONString(parameterMap, SerializerFeature.PrettyFormat);
        } else {
            params = JSON.toJSONString(apiParam, SerializerFeature.PrettyFormat);
        }
        if (ex instanceof InvocationTargetException) {
            Throwable targetException = ((InvocationTargetException) ex).getTargetException();
            ex = (Exception) targetException;
        }
        if (ex instanceof HttpMediaTypeException) {
            ex = new BadRequestException();
        }
        if (ex instanceof HttpRequestMethodNotSupportedException) {
            ex = new BadRequestException();
        }
        if (ex instanceof BadRequestException) {
            // 参数不完整
            response.setStatus(((BadRequestException) ex).getCode());
        } else if (ex instanceof UnauthorizedException) {
            // 当前设备已被登出
            response.setStatus(((UnauthorizedException) ex).getCode());
        } else if (ex instanceof NoAuthException) {
            // 未登录
            response.setStatus(((NoAuthException) ex).getCode());
        } else if (ex instanceof OvertimeException) {
            // 请求超时
            response.setStatus(((OvertimeException) ex).getCode());
        } else if (ex instanceof BizMsgException) {
            // 业务异常
            resultBean = new ResultBean((BizMsgException) ex);
        } else {
            // 未知异常
            // 上报记录
            resultBean = new ResultBean(new BaseException(ErrorMsgEnum.ERROR, "The service is being upgraded. Please try again later."));
            log.error(ex, ERROR, request.getRequestURI(), params);
        }
        log.warn(ex, ERROR, request.getRequestURI(), params);
        return resultBean;
    }

}
